#pragma once

// for pthreads
#define _REENTRANT

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cerrno>
#include <string>
#include <ctime>

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include "../common/log.hpp"
#include "Socket.h"
#include "../common/Settings.hpp"
#include "TCPListenerSubscriber.hpp"

namespace efs
{

/** \brief
* This class realises all low level socket operations.
*/
class TCPListener
{
public:
	/**
	* Constructor.
	* \param port TCP-IP port that would be listened.
	*/
	TCPListener(int port);

	/**
	* Listeneng start.
	* \return Is server starting OK.
	*/
	bool startListening(void);

	/**
	* Listeneng stop.
	*/
	void stopListening(void);

	void setSubscriber(TCPListenerSubscriber *subscriber);


private:
	int m_port;
	int m_listener;
	pthread_t m_thread;
	bool m_stop_req;
	const int m_buff_size;
	const int m_wait_timeout;

	// Structure for non-synch reading
	fd_set m_readset;

	TCPListenerSubscriber *m_subscriber;

	void printError(std::string func_name) const;
	static void * threadProc (void *vptr_args);
	bool preparem_listener();
	void waitRequest(void);
	bool closeAll(void);

	TCPListener (TCPListener &);
	TCPListener & operator=(TCPListener &);
};
}

